package org.dei.perla.sys.device.channel.frame.sender;

import org.dei.perla.sys.device.channel.frame.Frame;
import org.dei.perla.sys.device.channel.frame.FrameConfiguration;

/**
 * Questa classe permette di inviare frames headerless
 */
public class FrameSenderHeaderLess extends FrameSender {

	/**
	 * Inizializza un oggetto per inviare frames headerless
	 * @param parConfiguration Configurazione frame
	 */
	public FrameSenderHeaderLess(FrameConfiguration parConfiguration) {
		super(parConfiguration);

	}

	@Override
	protected void pBufferInitialize() {
		reset();
		this.pBuffer[this.pBufferCount++] = this.pConfiguration
				.getByteDelimiterStartHeaderLess();
	}

	@Override
	public byte[] forgeFrame(Frame parFrame) {

		this.pBufferInitialize();

		for (byte tByte : parFrame.getPayload()) {
			pAppendByte(tByte);
		}

		return pGetFrame();
	}

	@Override
	protected boolean pAppendByte(byte parByteToAppend) {
		
		boolean tByteEscaped;

		// Inizializza le variabili
		tByteEscaped = false;

		// Verifica che ci sia spazio sufficiente nel buffer di invio..
		if (this.pByteCount < this.pConfiguration.getBufferSize()) {

			// Se il byte da inviare è un escape, costruisce l'opportuna sequenza di escape
			if (parByteToAppend == this.pConfiguration.getByteEscape()) {
				tByteEscaped = true;
			}

			// Se il byte da inviare è un delimitatore di inizio frame, costruisce l'opportuna sequenza di escape
			else if (parByteToAppend == this.pConfiguration.getByteDelimiterStartHeaderLess()) {
				tByteEscaped = true;
			}

			// Se il byte da inviare è un terminatore, costruisce l'opportuna sequenza di escape
			else if (parByteToAppend == this.pConfiguration.getByteDelimiterEnd()) {
				tByteEscaped = true;
			}

			// In tutti gli altri casi invia il byte inalterato
			else {
				tByteEscaped = false;
			}

			// .. aggiunge al buffer l'eventuale escape 
			if (tByteEscaped) {
				this.pBuffer[this.pBufferCount++] = this.pConfiguration.getByteEscape();
			}
				
			// .. aggiunge al buffer il byte da inviare
			this.pBuffer[this.pBufferCount++] = parByteToAppend;

			// .. aggiorna il conteggio dei byte nel buffer
			this.pByteCount++;

			return true;
		}
		
		this.pNotifyBufferOverflow(parByteToAppend);
		
		return false;
	}

}
